
/**
 * Component节点
 */
export class FormComponent {
    id: string;

    public type = 'Component';
    /**
     * 组件对应的ViewModel ID
     */
    public viewModel: string;
    /**
     * 组件类型
     */
    public componentType: FormComponentType | any;
    /**
     * 组件内容
     */
    public contents: any[];
    /**
     * 初始化事件
     */
    public onInit?: string;
    /**
     * 视图加载后事件
     */
    public afterViewInit?: string;
    /**
     * 组件展示类型：弹出式（modal，目前用于子表弹出卡片式编辑的场景）
     */
    public showType?: string;

    /** 标记删除 */
    public fakeDel?: boolean;

    /** 移动自定义样式 */
    public customClass?: string;
}

/**
 * 组件类型
 */
export enum FormComponentType {
    /**
     * 表单
     */
    Frame = 'Frame',

    /**
     * 列表/树表类
     */
    dataGrid = 'dataGrid',


    /**
     * 列表视图
     */
    listView = 'listView',

    /**
     * 卡片类（待优化，目前类型中带有控件列布局信息）
     */
    form = 'form',

    /**
     *  附件
     */
    attachmentPanel = 'attachmentPanel',

    /**
     * 子表弹出编辑后创建的模态框组件---运行态是动态创建的
     */
    modalFrame = 'modalFrame',

    /** 表格类 */
    table = 'table',

    /** 预约日历 */
    appointmentCalendar = 'appointmentCalendar'
}


/**
 * DOM 控件binding实体
 */
export class FormBinding {
    public type: FormBindingType;
    public path: string;
    public field: string;
    public fullPath: string;

    // 目前附件上传组件记录bindingPath
    public bindingPath?: string;
}

/**
 * binding 类型
 */
export enum FormBindingType {
    Form = 'Form',
    Variable = 'Variable'
}



/**
 * dom Json ViewModel 节点实体
 */
export class FormViewModel {
    public id: string;
    public code: string;
    public name: string;
    public fields: FormViewModelField[];
    public commands: any[];
    public states: FormVariable[];
    public serviceRefs: any[];
    public bindTo: string;
    public parent?: string;
    public enableUnifiedSession?: boolean;
    public pagination?: FormViewModelPagination;
    public stateMachine?: string;

    public fakeDel?: boolean;

    /** 启用校验 */
    public enableValidation?: boolean;

    /** 实体数据是否允许为空 */
    public allowEmpty?: boolean;

}

/**
 * dom Json ViewModel 节点中fields实体
 */
export class FormViewModelField {
    public type: string;
    public id: string;

    // 字段bindingField
    public fieldName: string;

    // 分组
    public groupId: string;
    public groupName: string;

    // 字段变更增量
    public fieldSchema?: any;

    // 字段变化前后事件
    public valueChanging?: string;
    public valueChanged?: string;

    // 更新时机
    public updateOn?: string;
}

/**
 * dom Json ViewModel 节点中states实体
 */
export class FormVariable {
    public id: string;
    public code: string;
    public name: string;
    public value?: any;
    public type: string;
    public category = 'locale';
    public fields?: any[];
    public defaultValue?: any;
}

/**
 * 变量类型
 */
export enum FormVariableCategory {
    locale = 'locale',
    remote = 'remote'
}

/**
 * 支持的变量类型
 */
export const FormVariableTypes = [
    { text: '字符串', value: 'String' },
    { text: '数字', value: 'Number' },
    { text: '布尔', value: 'Boolean' },
    { text: '日期', value: 'Date' },
    { text: '日期时间', value: 'DateTime' },
    { text: '文本', value: 'Text' },
    { text: '对象', value: 'Object' },
    { text: '数组', value: 'Array' }
];

/**
 * DOM GridField 中的数据类型
 */
export enum GridFieldDataType {
    string = 'string',
    boolean = 'boolean',
    date = 'date',
    number = 'number',
    enum = 'enum',
    datetime = 'datetime'
}

/**
 * 枚举类型
 */
export class EnumData {
    public value: string;
    public name: string;
}

/**
 * Item类型数据
 */
export class ItemData {
    public value: string;
    public name: string;
}


/**
 * vm 分页配置
 */
export class FormViewModelPagination {
    public enable: boolean;
    public pageList?: string;
    public pageSize?: number;
}

/**
 * 组合表单-声明实体
 */
export class FormDeclaration {
    public events?: DeclarationEvent[];
    public commands?: DeclarationCommand[];
    public states?: DeclartionState[];
}

/**
 * 组合表单-事件声明实体
 */
export class DeclarationEvent {

    hId?: string;
    /** 事件类型：控件的事件/实体的事件 */
    public type: 'controlEvent' | 'fieldEvent';
    /** 编号 */
    public code: string;
    /** 名称 */
    public name: string;
    /** 事件 */
    public event: string;
    /** 控件路径 */
    public path: string;

    public params: DeclarationParam[];

    /** 实体上的字段值变化事件：保存字段在视图模型上的路径 */
    public fieldPath?: string;

}

/**
 * 组合表单-参数实体
 */
export class DeclarationParam {
    public hId?: string;
    /** 编号 */
    public code: string;
    /** 名称 */
    public name: string;
    /** 参数值 */
    public value: string;
}

/**
 * 组合表单-命令声明实体
 */
export class DeclarationCommand {
    /** ID */
    public hId?: string;
    /** 命令编号 */
    public code: string;
    /** 命令名称 */
    public name: string;
    /** 命令 */
    public command: string;
    /** 路径 */
    public path: string;
    /** 命令所在的组件ID */
    public componentId: string;

}


/**
 * 组合表单-变量声明实体
 */
export class DeclartionState {
    public hId?: string;
    /** 编号 */
    public code: string;
    /** 名称 */
    public name: string;
    /** 变量 */
    public state: string;
    /** 变量路径 */
    public path: string;
}

/**
 * 组合表单-订阅实体
 */
export class Subscription {
    /** 唯一标识 */
    public hId?: string;
    /** 源表单 */
    public sourceComponent: string;
    /** 原表单的事件编号 */
    public subscribeOn: string;
    /** 目标表单 */
    public targetComponent: string;
    /** 目标表单的命令编号 */
    public invoke: string;
    /** 目标表单的命令所在的组件ID */
    public invokeComponentId: string;
    /** 参数 */
    public paramMappings: SubscriptionParamMapping[];
}

/**
 * 组合表单-订阅参数实体
 */
export class SubscriptionParamMapping {
    /** 源参数编号 */
    public sourceCode: string;
    /** 目标参数编号 */
    public targetCode: string;
    /** 目标参数类型 */
    public targetType: string;
    /** 目标参数路径 */
    public targetPath: string;
}

/**
 * 表达式配置
 */
export class FormExpression {
    public fieldId: string;
    /** 其实存的是componentId */
    public viewModelId?: string;
    public expression: Array<FormExpressionConfig>;
}

/**
 * 表达式配置
 */
export class FormExpressionConfig {
    id: string;
    /**
     * 表达式类型
     */
    type: string;
    /**
     * 表达式配置值
     */
    value: string;
    /**
     * 提示消息
     */
    message?: string;
    /**
     * 提示消息类型
     */
    messageType?: string;

}

/**
 * 引入的外部组件
 */
export class FormExternalComponent {

    id: string;
    uri?: string;
    name?: string;
    code?: string;
    /**
     * 导入组件（表单）的文件名：ExternalContainer下必填、内嵌表单类的ModalContainer必填，url类的ModalContainer为空
     */
    fileName?: string;
    /**
     * 导入组件（表单）的路径：ExternalContainer下必填、内嵌表单类的ModalContainer必填，url类的ModalContainer为空
     */
    filePath?: string;
    /**
     * 导入的组件（表单）的声明
     */
    declarations?: any;
    /**
     * 容器类型
     */
    type: string;
    /**
     * 由ExternalContainer、ModalContainer引入的外部组件，containerId是容器id
     * 由筛选方案中智能输入框引入的弹出表单：containerId是绑定字段id
     */
    containerId: string;
    /**
     * 弹窗容器ModalContainer 区分内容类型
     */
    contentType?: string;

    /**
     * 弹窗容器ModalContainer 内容类型为URL的场景
     */
    url?: string;

    /**
     * 是否独立加载js脚本
     */
    useIsolateJs?: boolean;

    /**
     * 组件所在工程名----用于独立加载js脚本
     */
    projectName?: string;
    /**
     * 组件所在su----用于独立加载js脚本
     */
    serviceUnitPath?: string;

    /** 导入组件（表单）所在的命名空间 */
    nameSpace?: string;
}

/**
 * 构件
 */
export class FormWebCmd {
    public id: string;
    public code?: string;
    public path: string;
    public name: string;
    public nameSpace?: string;

    /** 命令的引用： host：视图模型中命令的id；handler：构件中命令的编号 */
    public refedHandlers?: Array<{ host: string; handler: string }>;

}
export class FormStateMachine {
    /** 标识 */
    public id: string;
    /** 状态机元数据编号 */
    public code: string;
    /** 状态机元数据名称 */
    public name: string;
    /** 状态机元数据id */
    public uri: string;
    /** 状态机元数据命名空间 */
    public nameSpace?: string;
}



/** TODO 替换为farris idService */
class Guid {
    static newGuid() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            // tslint:disable-next-line:no-bitwise
            const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }
}
